2: COMMENT ⊗ VALID 00038 PAGES 3: C REC PAGE DESCRIPTION 4: C00001 00001 5: C00005 00002 BEGIN LINED 6: C00007 00003 GLOBAL LINE,KBDCHN,CHR 7: C00010 00004 COMMENT KBDED IS CALLED AT UUO OR INTERRUPT LEVELS FROM RECINT, WITH CHR CONTAINING 8: C00014 00005 KBDBEG: 9: C00020 00006 LECCN: PUSH P,I SAVE THE DPY PROGRAM HEADER ADDRESS 10: C00021 00007 LEC1: JUMPE UCHN,LECB 11: C00023 00008 LE2CR: PUSHJ P,LECT SIMULATE A CTRL TAB (GO TO END OF LINE). 12: C00025 00009 LE2A: TRNN UCHN,CBIT2 INSERT CHAR. IF CTRL 2. OR CTRL1 (OR BOTH) 13: C00028 00010 SUBROUTINES FOR INSERTING CHARACTERS IN THE LINE. 14: C00031 00011 INSTAB: MOVEI CHR," " A TAB. PREPARE TO (SIGH) SIMULATE IT. 15: C00034 00012 THIS IS THE LINE EDITOR'S GARBAGE COLLECTOR. IT GOES THROUGH THE 16: C00037 00013 ROUTINES TO PERFORM EDITING FUNCTIONS. 17: C00040 00014 LEBS: CAIN UCHN,CBIT2!CBIT1 18: C00042 00015 LECI: TLOE I,INSBT FLAG INSERT MODE. 19: C00044 00016 THIS ROUTINE ADJUSTS THE NEXT TAB, AS GIVEN BY THE BYTE POINTER IN TAC. 20: C00046 00017 SEARCH: MOVEI AC1,1 PREPARE TO SEARCH FOR INDICATED CHR. 21: C00048 00018 LEDESC: CAIN CHR,10044 22: C00050 00019 WE GET HERE IF THE LOSER TYPES <ESC>C OR <ESC>¬C WHICH CAUSES 23: C00052 00020 ROUTINE TO PUT PAGE PRINTER IN HOLD 24: C00054 00021 ROUTINE TO SET PAGE PRINTER GLITCHES/PAGE 25: C00055 00022 ESCAPE W,Q. 26: C00058 00023 ESCAPE O,F,I,X. 27: C00061 00024 FNTAB: TLO I,NOTABB PREPARE TO FIND NEXT TAB IN LINE. 28: C00063 00025 MOVEIT MOVES THE PTR. FORWARD OR BACKWARD BY THE NO. OF PLACES 29: C00066 00026 INIT2: MOVE TAC,ACTMOD(DDB) GET SPECIAL BITS 30: C00069 00027 THIS IS THE INITIALIZE ROUTINE. HERE WE INITIALIZE ALL THE LINE 31: C00072 00028 ↑LACTIV:TDZA UCHN,UCHN NO SPURIOUS CTRL BITS PLEASE. 32: C00077 00029 WE GET HERE WHEN THE LINE EDITOR BUFFER IS EMPTY. 33: C00079 00030 ACTIV2: TLO IOS,SYNC!DDTM FORCE ACTIVATION 34: C00081 00031 ECHOCB: TRNN IOS,NOECHB IS USER SUPPRESSING ECHO OF CTRL. BITS ? 35: C00083 00032 HERE IS WHERE WE QUEUE UP LINE EDITOR TRANSFERS 36: C00084 00033 THIS IS A ROUTINE THAT GOES THROUGH THE LINE AND SETS UP EXTRA CRLFS TO BREAK 37: C00086 00034 WE GET HERE IF THE LINE IS LONG AND MUST BE BROKEN UP. 38: C00088 00035 HERE WE SEE IF THE TAB IS A REAL TAB OR IF IT IS JUST 39: C00090 00036 WE GET HERE WHEN THE TAB SURROUNDS A BUNCH OF SPACES. FIRST WE 40: C00093 00037 AT THIS POINT, WE ARE IN THE PROCESS OF BREAKING A LONG LINE 41: C00095 00038 MAKE11: POP P,AC3 RESTORE COLUMN COUNT 42: C00096 ENDMK 43: C⊗; 45: BEGIN LINED 46: 47: COMMENT ⊗ THIS IS THE INCREDIBLE INTRA-LINE EDITOR. ITS FEATURES ARE: 48: 49: CTRL1 SPACE-- MOVE FORWARD THROUGH LINE. 50: CTRL BS-- MOVE BACKWARD. 51: BS -- MOVE BACKWARD, DELETING .(END OF LINE ONLY) 52: CTRL I -- ENTER INSERT MODE (MIDDLE OF LINE ONLY). 53: CTRL D -- DELETE FORWARD (MIDDLE OF LINE ONLY). 54: CTRL TAB -- MOVE TO END OF LINE. 55: CLEAR -- DELETE ENTIRE LINE. 56: CTRL S<ANY CHR.> -- MOVE POINTER RIGHT TO NEXT OCCURRENCE OF <ANY CHR.>. 57: CTRL K<ANY CHR.> -- DELETE RIGHT TO NEXT OCCURRENCE OF <ANY CHR.>. 58: 59: CTRL CR -- AT START OF LINE ONLY, RETRIEVES THE LAST LINE TYPED IN. 60: 61: CHARACTERS TYPED WITH META IN THE MIDDLE OF THE LINE WILL BE INSERTED. 62: 63: ANY COMMAND MAY BE PRECEDED BY A REPEAT NUMBER (TYPED WITH CTRL BUTTON). 64: FOR EXAMPLE, CTRL 9 CTRL BS MOVES THE POINTER BACK 9 CHARACTERS. 65: ANY CTRL COMMAND LEAVES INSERT MODE. 66: 67: WHAT COULD BE MORE WONDERFUL ?? 68: ⊗ 69: 71: GLOBAL LINE,KBDCHN,CHR 72: 73: I←ITEM 74: 75: CBIT1←←1 ;CTRL BIT 1. 76: CBIT2←←2 ;CTRL BIT 2. 77: EOLCHR←←12 ;LINE FEED TERMINATES THE LINE IN THE BUFFER. 78: 79: ;;STATUS BITS (LEFT HALF OF I). 80: 81: SRCHBT←←400 ;CTRL1 S SEEN, NEXT CHR. IS SEARCH ARGUMENT. 82: KILLBT←←1000 ;CTRL1 K SEEN.... 83: ↑WTFLAG←←1 ;WAITING FOR PRGM. TO SWALLOW LAST LINE. 84: EOLBT←←2 ;AT END OF LINE. 85: INSBT←←4 ;INSERT MODE (MIDDLE OF LINE). 86: TABB←←10 ;LOCATION OF NEXT TAB IN NTABPT, SIZE IN NTABCT. 87: NOTABB←←20 ;NO TAB BETWEEN CURRENT POS. AND END OF LINE. 88: XTABBT←←100 ;WE ARE INSIDE A TAB IN GETEM. 89: REEDBT←←2000 ;WE ARE RE-EDITING A LINE (AFTER A CTRL1 CR). 90: NOCRBT←←4000 ;WE SHOULD NOT PUT ANOTHER CR INTO THIS LINE. 91: NOTEXT←←10000 ; THIS BIT MEANS THE TEXT HAS NOT BEEN CHANGED, JUST THE CURSOR 92: NOTFR←←20000 ; MEANS THAT NO TRANSFER AT ALL SHOULD TAKE PLACE 93: CRBIT←←40000 ; USED TO SKIP OVER CRLF IN MIDDLE OF LINE 94: NOBRBT←←100000 ; MEANS LINE HAS NOT BEEN BROKEN UP. LONG LINES ONLY. 95: ACTNOW←←200000 ; MEANS WE SHOULD ACTIVATE NOW 96: SHLDRB←←200 ;Loser wants to see every chr. we see. 97: 98: ;; NOW SOME DISPLAY OPCODES AND MACROS FOR GENERATING DP INSTRS. 99: 100: DISJMP←←20 ;DP JMP INSTR. OPCODE. 101: DISJMS←←4 ; JMS (STORES TWO WORDS) 102: DISJSR←←24 ; STORES ONLY RETURN ADDR. 103: DISRST←←14 ;RESTORE. 104: DISSEL←←10 ;SELECT. 105: DISNOP←←12 ;ACTUALLY TSS, BUT A GOOD NOP WITH ALL BITS OFF. 106: 107: DEFINE LVW(X,Y,TYPE,MODE,BRT,SIZ) ;ASSEMBLES A LONG VECTOR. 108: { MVW1 (MODE,TYPE,BRT,SIZ) ;TWIDDLE PARAMS. 109: BYTE (11)<X>,<Y>(3)B,S(2)MD,TT(3)3 } ;ASSEMBLE INSTR. 110: DEFINE MVW1 (M,T,BRT,SIZ) 111: {IFIDN {M}{A}{MD←←1;}MD←←0 ;MODE = `A' FOR ABSOLUTE. 112: IFIDN {T}{I}{TT←←2;}TT←←0 ;TYPE = `I' FOR INVISIBLE. 113: IFIDN {BRT}{}{B←←0;}B←←BRT ;BRT = 0 IF OMITTED. 114: IFIDN {SIZ}{}{S←←0;}S←←SIZ ;SAME FOR SIZ. 115: } 116: 117: ↑↑XDEL: 14B10 ;X-SIZE OF A SIZE 2 CHARACTER, POSTIONED AT THE X-FIELD. 118: XDEL2: 14B11 ;ONE HALF OF ABOVE. 120: COMMENT ⊗ KBDED IS CALLED AT UUO OR INTERRUPT LEVELS FROM RECINT, WITH CHR CONTAINING 121: THE CHAR. TO BE CONSIDERED WITH ITS CTRL BITS IN PLACE. UCHN CONTAINS 122: JUST THE CTRL BITS, RIGHT JUSTIFIED, AND DSER CONTAINS THE LOWER-CASE 123: VERSION OF THE CHARACTER IN CHR. DDB AND LINE ARE SETUP TO THE RIGHT 124: TTY, AS IS IOS. PROG, IOS, AND UUO ARE PRESERVED BY KBDED. 125: ⊗ 126: 127: ↑KBDED: 128: IFN FTOIKB, < CAIN CHR,10000 ;<CTRL 2> LINE FEED IS FOR ↑O. 129: ; HANGOVER FOR III KEYBOARDS 130: JRST CONTOB ;CONTOB IS IN TTEDIT. > 131: MOVE DAT,LINE ;GET DPY NO. AND LINTAB BITS INTO DAT. 132: MOVE I,LETAB-DPYL0(DAT) ;LOAD I WITH PRT. TO CONTROL BLOCK AND BITS 133: TLZ I,NOTEXT!NOTFR!CRBIT 134: SETOM LEINV(I) ; SET BUFFER INVALID 135: SETOM LEACT(I) ; MAKE SURE WE STICK AROUND FOR ANOTHER MINUTE 136: TLNE I,SHLDRB ;Loser looking over our shoulder ? 137: PUSHJ P,LSRSEE ;Hold up chr. for him to see. Hope he likes it. 138: PUSHJ P,KBDBEG ; DO LINE EDITOR BIT 139: SETZM LEINV(I) 140: TLZE I,NOTFR ; WAS THIS A SILENT COMMAND? 141: JRST KBDX1 ; YES, JUST LEAVE QUIETLY 142: TLNE I,NOTEXT ; HAS THE TEXT BEEN CHANGED? 143: PUSHJ P,QLECUR ; NO, JUST UPDATE THE CURSOR 144: TLZE I,NOTEXT 145: KBDX1: SKIPE LEWAKE(I) ; DID WE CAUSE A TRANSFER TO ABORT? 146: PUSHJ P,QLETXT ; YES, UPDATE BOTH 147: SETZM LEWAKE(I) ; CLEAR ABORT FLAG 148: HRRZ DAT,PRGNUM(I) ; PICK UP DPY NUMBER 149: HLLM I,LETAB(DAT) 150: TLNE I,WTFLAG ;ARE WE CURRENTLY ACTIVATING SOMETHING? 151: POPJ P, ;YES, SNEAK WILL GET WOKEN UP LATER! 152: TLNE IOS,SNKWAT ; IN SNEAK WAIT? 153: SKIPG CCPOS(I) ; ANYTHING FOR HIM TO SEE? 154: POPJ P, 155: KBDX2: MOVE IOS,[XWD TTYIOW!SNKWAT,IOACT] ;YES, CLEAR FLAGS 156: ANDCAB IOS,DEVIOS(DDB) 157: JRST STTIOD ;BRING HIM OUT OF WAIT 158: 159: LSRSEE: PUSH P,DAT 160: MOVEI DAT,TTIBUF(DDB) 161: PUSHJ P,PUTCHI ;Put chr. in loser's input buffer. 162: JFCL ;Buffer full. Loser loses. 163: MOVE AC1,TIFCTR(DDB) 164: CAIG AC1,TTICHR/4 ;Is his buffer getting full ? 165: TLNN IOS,TTYIOW ;Is he waiting for input ? 166: JRST LSRSEX ;No. 167: PUSHJ P,SYNCHA ;Prepare to activate loser. 168: PUSHJ P,KBDX2 ;Wake him up. 169: LSRSEX: POP P,DAT 170: POPJ P, 172: KBDBEG: 173: ;DONT MOVE AC2,TIME ; PICK UP TIME OF DAY 174: ;SAVE SKIPN DPKTIM(I) ; HAS THE TIME BEEN STORED YET? 175: ;TIME MOVEM AC2,DPKTIM(I) ; NO, DO SO 176: SKIPE III(I) 177: JRST KBDBG1 178: MOVE AC3,CURPP(I) 179: MOVE AC2,DPHPOS(AC3) 180: SKIPGE LEPOS(I) 181: TDZA AC2,AC2 182: ADD AC2,LNLNGT(AC3) 183: MOVEM AC2,PPHPOS(I) 184: KBDBG1: TRNE CHR,10000 185: JRST LEDESC ;<ESC>SOMETHING 186: TRNN CHR,177 ;IS THIS MAYBE A CALL? 187: JRST LECCN ;A CALL WILL BE A NULL NOW. 188: JUMPL I,NOINIT ;IS THIS THE FIRST CHAR OF A LINE? 189: TLNE I,WTFLAG ;YES, IS LAST LINE IN USER BUFFER YET? 190: JRST TPOPJ ;NO, JUST IGNORE HIM 191: PUSHJ P,INIT2 ;CLEANSE THE WORLD 192: NOINIT: ANDI CHR,177 ;REMOVE CTRL BITS FROM CHR. 193: CAIL CHR,"a" ;IS IT A LOWER CASE LETTER ? 194: CAILE CHR,"z" 195: JRST LE20 ;NO. 196: ; TLNN IOS,TPMON ;YES. IF MONITOR MODE OR 197: TLNN DAT,FCS ; NOT FULL CHAR. SET MODE, 198: SUBI CHR,40 ; CONVERT TO UPPER CASE. 199: LE20: TLZE I,SRCHBT ;WAS LAST CHR. AN S OR K COMMAND ? 200: JRST SEARCH ;YES. 201: CAIE CHR,177 ;IF IT'S A BACKSPACE, PRETEND IT HAS CTRL 1. 202: CAIN UCHN,CBIT1 ;DO WE HAVE CTRL 1 ONLY ? 203: TLNE IOS,DDTM ;YES. IS EDITOR DISABLED ? 204: JRST LE2 ;NOT A COMMAND. GO PUT IT IN BUFFER. 205: CAIG CHR,"9" ;IS IT A DIGIT ? 206: CAIGE CHR,"0" 207: JRST LEC1 ;NO. 208: MOVE AC1,NUMARG(I) ;YES. CTRL NUMBERS ARE PART OF REPEAT ARGUMENT. 209: IMULI AC1,=10 ;DO DECIMAL CONVERSION. 210: ADDI AC1,-"0"(CHR) 211: ANDI AC1,777 ;DON'T LET IT GET TOO BIG. 212: MOVEM AC1,NUMARG(I) 213: POPJ P, 215: LECCN: PUSH P,I ; SAVE THE DPY PROGRAM HEADER ADDRESS 216: PUSHJ P,RECINB 217: POP P,I 218: HRRZ DAT,LINE ; RECINB CLOBBERS THIS 219: SETZ AC1, 220: EXCH AC1,DPHOLD(I) 221: JUMPE AC1,LFLUSH 222: HRRZ AC1,PRGNUM(I) 223: ADD AC1,[XWD UNHOLD,DPYL0] 224: CONO PI,PIOFF 225: IDPB AC1,CLKQ 226: CONO PI,PION 227: LFLUSH: PUSH P,DDB ;SAVE AN AC 228: MOVEI DDB,LEB(I) ;TURN OFF EDITOR BUFFER BY 229: HRLI DDB,DISJMP ;PUTTING A RETURN JUMP 230: MOVSM DDB,LEPPV(I) ;ON TOP OF THE POSITION VECTOR. 231: ; PUSHJ P,INIT1 ;COMMENTED OUT BY FW SO CTRL-CR WILL WORK 232: POP P,DDB 233: HRRZS I,LETAB-DPYL0(DAT);RESET STATUS 234: POPJ P, 236: LEC1: JUMPE UCHN,LECB 237: MOVE AC1,XDEL ;GET X DIMENSION OF A CHR. 238: TLZE I,INSBT ;LEAVE INSERT MODE, IF WE ARE IN IT. 239: PUSHJ P,INSP1 ;READJUST CURSOR POSITION. 240: LECB: SKIPN AC1,NUMARG(I) ;DID GUY TYPE RPT ARG ? 241: AOS AC1,NUMARG(I) ;NO. USE 1. 242: CAIN CHR,177 243: JRST LEBS ;BACKSPACE. 244: CAIN CHR," " 245: JRST LECSP ;CTRL1 SPACE. 246: CAIN CHR,14 247: JRST LECFF 248: TLNE I,EOLBT ; AT END OF LINE? 249: JRST LE2 ; YES, USER GETS TO SEE CTRL LETTERS. 250: TRZ DSER,40 ;CHANGE LOWER CASE LETTERS TO UPPER. 251: CAIN DSER,"D" ;COMPARE UNSHIFTED CHAR. 252: JRST LECD 253: CAIN DSER,"I" 254: JRST LECI 255: CAIN CHR,11 ;A TAB ? 256: JRST LECT 257: CAIN DSER,"K" 258: TLOA I,KILLBT 259: CAIN DSER,"S" 260: TLOA I,SRCHBT 261: JRST LE2 ;RANDOM CTRL LETTER. 262: JRST LECX1 ;STORE NEW BITS IN I AND EXIT. 263: 264: LECFF: MOVEI AC1,=200 ;SIMULATE 200 CTRL BS'S 265: MOVEM AC1,NUMARG(I) 266: JRST LEBS 268: LE2CR: PUSHJ P,LECT ;SIMULATE A CTRL TAB (GO TO END OF LINE). 269: MOVEI CHR,15 ; RESTORE THE CR THAT MAKECR CLOBBERS 270: 271: LE2: ;;HERE IF CHR HAS NO CTRL1 BIT. 272: TLNN I,EOLBT ;AT END OF LINE ? 273: JRST LE2A ;NO. 274: TLNE I,NOCRBT ;ARE WE RE-EDITING THIS LINE ? 275: CAIE CHR,15 ;YES. DON'T PUT ANOTHER CR AT ITS END. 276: SKIPA 277: JRST ACTIV1 ;JUST ACTIVATE GUY WHEN HE TYPES CR AT A RE-EDITED LINE. 278: PUSHJ P,PUTCHR ;PLACE CHAR. IN BUFFER. 279: MOVEM TAC,FCPOS(I) ;UPDATE FINAL CHAR. POS. CTR. 280: JUMPG UCHN,ACTIV1 ;ACTIVATE ON ANY CTRL BITS AT EOL. 281: 282: LE2X: MOVE TAC,SPCTAB(CHR) ;SPECIAL BITS. 283: TLNN TAC,BREAKB!FCSBRK ;A BREAK CHAR. ? 284: TLNE IOS,DDTM ;IS EVERY CHAR. AN ACTIVATOR ? 285: JRST ACTIV1 ;YES. 286: TLZE I,ACTNOW ; ARE WE OUT OF BUFFER SPACE? 287: JRST ACTIV1 ; YES, ACTIVATE NOW 288: TLNE DAT,SPCBRK ;ARE WE IN SPECIAL ACTIVATION MODE? 289: TLNE IOS,TPMON 290: JRST LE2XA ;NO 291: PUSHJ P,SPCACT ;TEST FOR BREAK. 292: CAIA 293: LE2XA: TRNE UCHN,CBIT1 ;YES. ANY CTRL BITS ? 294: JRST ACTIV1 ;YES. 295: JRST LECX 297: LE2A: TRNN UCHN,CBIT2 ;INSERT CHAR. IF CTRL 2. OR CTRL1 (OR BOTH) 298: TLNE I,INSBT ;ARE WE IN INSERT MODE ? 299: JRST LEINS ;YES. 300: CAIN CHR,15 301: JRST LE2CR ;CR'S GO AT END OF LINE. 302: TRNE UCHN,CBIT1 ;NOW TEST CTRL BIT 1 303: JRST LEINS ;INSERT 304: LEOV: PUSH P,CHR ;WE'RE OVER-STRIKING. SAVE CHAR. 305: MOVEI AC1,1 ;FAKE A RPT. ARG. OF 1. 306: MOVE TAC,LEPNT1(I) ;IF WE ARE ABOUT TO OVERSTRIKE 307: LEOVS: ILDB AC2,TAC ;A TAB, AND IF THE TAB IS MORE 308: JUMPE AC2,.-1 309: CAIE CHR,11 ;ALWAYS OVERTYPE IF NEW CHAR IS TAB 310: CAIE AC2,11 ; IS THIS A TAB? 311: JRST LEOVD ; NO, JUST GO AHEAD AND OVERSTRIKE. 312: ILDB AC3,TAC ;WE WILL INSERT INSTEAD. 313: JUMPE AC3,.-1 ; NO NULLS, PLEASE. 314: CAIE AC3," " ; IS THIS REALLY A TAB OR A LONG LINE CRLF? 315: JRST LEOVSC ; IS LONG LINE CRLF, READ PAST IT 316: ILDB AC3,TAC ; PICK UP CHARACTER PAST SPACE 317: JUMPE AC3,.-1 318: CAIN AC3,11 ;YES. MORE THAN ONE SPACE ? 319: LEOVD: PUSHJ P,LECD ;DELETE NEXT CHR. IN LINE. 320: POP P,CHR ;NOW INSERT NEW ONE. 321: LEINS: TLO I,NOBRBT ; FORCE REPOSITIONING OF THE LONG LINE CRLF 322: CAIE UCHN,CBIT2 ;IF INSERT VIA META, 323: JRST LEINS1 324: MOVEI UCHN, ; DON'T LET IT ACTIVATE IN SPECIAL ACT MODE 325: PUSHJ P,SPCACT ; UNLESS IT WOULD'VE WITHOUT META 326: MOVEI UCHN,CBIT2 327: LEINS1: PUSHJ P,PUTCHR ;PLACE NEW CHR. IN LINE. 328: AOS FCPOS(I) ;INC. TOTAL CHR. COUNT. 329: MOVNI AC3,1(AC3) ;- NO. OF COLUMNS INSERTED. 330: MOVE TAC1,LEPNT1(I) ;GET CURRENT POINTER. 331: PUSHJ P,ADJTB ;GO FIDDLE NEXT TAB IN LINE. 332: JFCL 333: JRST LE2X 334: 335: LEOVSC: ILDB AC3,TAC ; PICK UP NEXT CHARACTER 336: CAIE AC3,11 ; IS IT THE FINAL TAB YET? 337: JRST LEOVSC ; NO, LOOK SOME MORE 338: JRST LEOVS ; YES, NOW LOOK AGAIN. 340: ;;SUBROUTINES FOR INSERTING CHARACTERS IN THE LINE. 341: 342: PUTLF: MOVEI CHR,12 ;INVENT A LINE FEED. 343: AOS FCPOS(I) 344: PUTCHR: SETZB AC3,NUMARG(I) ;CLEAR REPEAT ARG. 345: PUSHJ P,INSCHR ;PLACE CHAR. INTO LINE. 346: MOVE AC2,XDEL ;PREPARE TO MOVE CURSOR. 347: CAIN CHR,11 ;DID WE INSERT A TAB ? 348: PUSHJ P,INSTAB ;YES. 349: ADDM AC2,LEPPV(I) ;MOVE CURSOR OVER ONE PLACE. 350: AOS DSER,LEHPOS(I) 351: CAILE DSER,=72 ;ARE WE AT RIGHT SIDE OF SCREEN ? 352: PUSHJ P,SHIFTL ;YES. SHIFT THE LINE LEFT SOME. 353: AOS TAC,CCPOS(I) ;CURRENT POSITION IN CHARS. 354: CAIN CHR,15 ;IS IT A CR ? 355: JRST PUTLF ;YES. 356: SKIPE III(I) ; IS THIS A DD DISPLAY? 357: POPJ P, ; NO, LEAVE NOW 358: PUSH P,AC3 ; SAVE NUMBER OF CHARACTERS INSERTED 359: MOVE AC3,CURPP(I) 360: MOVE AC1,PPHPOS(I) ;GET INITIAL X POSITION 361: ADD AC1,LEHPOS(I) ; ADD IN LINE EDITOR'S HORIZONTAL POSITION 362: CAIE CHR,11 ; WAS THE CHARACTER A TAB? 363: JRST PUTCH1 ; NO, BREAK ONLY IF EVENLY AT END OF LINE 364: ADDI AC1,4 ; CENTER TAB ON END OF SCREEN 365: IDIV AC1,LNLNGT(AC3) ; SEE IF SE ARE NEAR THE END OF THE LINE 366: CAIG AC2,10 ; WITHIN + OR - 4 CHARACTERS? 367: PUTCH2: TLO I,NOBRBT ; YES, DO LINE BREAKING CALCULATION THIS TIME 368: PUTCH3: POP P,AC3 ; RESTORE NUMBER OF CHARACTERS INSERTED 369: POPJ P, 370: 371: PUTCH1: SUBI AC1,1 372: IDIV AC1,LNLNGT(AC3) ; SEE IF WE ARE EXACTLY AT THE END OF THE LINE 373: JUMPE AC2,PUTCH2 ; YES, BREAK OUR LINE THIS TIME 374: JRST PUTCH3 ; RESTORE ACCUMULATOR AND LEAVE 376: INSTAB: MOVEI CHR," " ;A TAB. PREPARE TO (SIGH) SIMULATE IT. 377: MOVE AC1,LEHPOS(I) ;GET LINE EDITOR HPOS 378: SKIPN III(I) 379: ADD AC1,PPHPOS(I) ;MAKE IT ABSOLUTE ON DD 380: ANDCAI AC1,7 ;HOW MANY SPACES TO INSERT (LESS 1). 381: ADDM AC1,LEHPOS(I) 382: SKIPA AC3,AC1 ;REMEMBER THE MAGIC NUMBER. 383: INST1: ADDM AC2,LEPPV(I) ;MOVE CURSOR OVER ONE PLACE. 384: PUSHJ P,INSCHR ;INSERT A SPACE IN THE LINE. 385: SOJGE AC1,INST1 ;BACK FOR MORE IF APPROPRIATE . 386: MOVEI CHR,11 ;NOW FINISH OFF WITH ANOTHER TAB. 387: INSCHR: ILDB TAC,LEPNT1(I) ;LOOK AT NEXT CHR. 388: JUMPE TAC,INSCH1 ;IF NULL, PUT NEW CHR. ON TOP OF IT. 389: MOVE TAC,LEPNT1(I) ;GET PTR. 390: PUSHJ P,LEINSW ;INSERT A WORD OF NULLS. 391: INSCH1: DPB CHR,LEPNT1(I) ;PUT NEW CHR. IN LINE. 392: POPJ P, 393: 394: LEINSW: AOS DSER,LELWD(I) ;UPDATE PTR. TO RETURN JMP. 395: CAMLE DSER,MAXPT(I) ;MORE ROOM IN BUFFER ? 396: PUSHJ P,GCOLL ; BUFFER NEARLY FULL, COMPRESS OUT ALL THE NULLS 397: INSW1: MOVE TAC1,(DSER) ;GET WORD FROM BUFFER AND 398: MOVEM TAC1,1(DSER) ;MOVE IT UP ONE. 399: CAILE DSER,(TAC) ;ARE WE DOWN TO WHERE WE WILL INSERT THE NULLS ? 400: SOJA DSER,INSW1 ;NO. 401: MOVEI DSER,0 ;PREPEARE TO INSERT NULLS. 402: MOVE TAC1,TAC 403: IDPB DSER,TAC1 ;NULL NEXT CHAR. AFTER CURRENT ONE.. 404: IDPB DSER,TAC1 ;..AND ALSO NEXT 3 AFTER THAT. 405: IDPB DSER,TAC1 406: IDPB DSER,TAC1 407: TLZ I,TABB ;WE NO LONGER KNOW WHERE NEXT TAB IS. 408: POPJ P, 410: ; THIS IS THE LINE EDITOR'S GARBAGE COLLECTOR. IT GOES THROUGH THE 411: ; BUFFER AND COMPRESSES OUT ALL THE NULL CHARACTERS. IT MUST RESET THE 412: ; POINTER TO THE LAST WORD IN THE TABLE, LELWD, MUST RESET THE BYTE POINTERS 413: ; IN LEPNT1 AND IN TAC. 414: 415: GCOLL: PUSH P,AC1 ; FIRST, SAVE A FEW ACCUMULATORS 416: PUSH P,AC2 417: PUSH P,AC3 418: PUSH P,UUO 419: MOVSI AC1,440700 ; NOW MAKE UP TWO BYTE POINTERS TO THE BUFFER 420: MOVSI AC2,440700 421: HRRI AC1,LEBUF(I) 422: HRRI AC2,LEBUF(I) 423: SETZ AC3, ; THIS WILL BE THE COUNT OF THE NULLS WE SQUEEZED OUT 424: GCOLL1: MOVE UUO,AC1 ; NOW, TEST FOR END OF BUFFER 425: IBP UUO ; SEE WHAT ADDRESS WE WOULD HAVE ENDED UP ON 426: HRRZS UUO ; CLEAN IT UP 427: CAML UUO,LELWD(I) ; COMPARE TO END OF BUFFER 428: JRST GCOLL4 429: ILDB UUO,AC1 ; PICK UP FIRST CHARACTER IN LINE 430: JUMPN UUO,GCOLL2 ; IF NOT A NULL, JUST STUFF IT IN THE BUFFER 431: ADDI AC3,1 ; ANOTHER NULL, COUNT IT 432: GCOLL3: PUSHJ P,PCHK ; UPDATE BYTE POINTERS IF NECESSARY 433: JRST GCOLL1 ; GO BACK FOR MORE 434: 435: PCHK: CAMN AC1,LEPNT1(I) ; ARE WE TO THE MAIN POINTER YET? 436: MOVEM AC2,LEPNT1(I) ; YES, UPDATE IT 437: CAMN AC1,TAC ; HAVE WE GOTTEN TO THE POINTER IN TAC YET? 438: MOVEM AC2,TAC ; YES, UPDATE IT TOO 439: POPJ P, 440: 441: GCOLL2: IDPB UUO,AC2 ; PUT THE CHARACTER DOWN IN ITS NEW POSITION 442: JRST GCOLL3 ; GO BACK FOR MORE 443: 444: GCOLL4: PUSHJ P,PCHK ; UPDATE FINAL POINTER 445: CAIGE AC3,5 ; DID WE COLLECT A FULL WORD OF NULLS? 446: TLO I,ACTNOW ; NO, ACTIVATE JOB NOW 447: HRRZI AC2,1(AC2) ; POINT FINAL POINTER TO LAST WORD IN BUFFER 448: MOVE UUO,@LELWD(I) ; PICK UP RETURN JUMP 449: MOVEM UUO,(AC2) ; PUT IT DOWN IN ITS NEW PLACE 450: MOVEM AC2,LELWD(I) ; AND THIS IS THE NEW END OF BUFFER POINTER 451: POP P,UUO ; RESTORE OUR ACCUMULATORS 452: POP P,AC3 453: POP P,AC2 454: POP P,AC1 455: POPJ P, 457: ;;ROUTINES TO PERFORM EDITING FUNCTIONS. 458: 459: LECT: MOVEI AC1,=200 ;A CTRL TAB. SIMULATE 200 CTRL SPACES. 460: LECSP: JSP TAC,CKNFOR ;CTRL SPACE. PREPARE TO MOVE CURSOR FORWARD. 461: PUSHJ P,MOVEIT ;MOVE IT. 462: MVFOR ;MOVE FORWARD, PLEASE. 463: TLO I,NOTEXT ; NOTE THAT WE HAVE ONLY CHANGED THE CURSOR POSITION, NOT THE TEXT 464: MVX1: MOVEM TAC1,LEPNT1(I) ;UPDATE THE BYTE POINTER. 465: MOVE DSER,AC2 466: MVX2: IMUL AC2,XDEL2 ;CALC. AMOUNT TO MOVE CURSOR. 467: LSH AC2,1 ;THIS IS TO HANDLE OVERFLOW. 468: SHIFT2: ADDM AC2,LEPPV(I) ;UPDATE THE POSITION VECTOR. 469: ADDB DSER,LEHPOS(I) ;UPDATE HORIZONTAL POS. CNT. 470: CAIG DSER,=72 ;PAST RIGHT HAND MARGIN ? 471: JUMPGE DSER,.+2 ;OR MAYBE PAST LEFT ? 472: PUSHJ P,SHIFT 473: LECX: TLZ I,SRCHBT!KILLBT 474: SETZM NUMARG(I) 475: LECX1: MOVE AC3,PPHPOS(I) 476: EXCH AC3,LSTHP(I) ; SEE THAT AS OUR NEW HORIZONTAL STARTING POSITION 477: CAMN AC3,LSTHP(I) ; IS IT THE SAME AS LAST TIME 478: TLZE I,NOBRBT ; OR HAS THIS LINE BEEN UNTOUCHED 479: PUSHJ P,MAKECR ; VIRGIN LINE OR DIFFERENT HORIZONTAL POSITION 480: TLZE I,ACTNOW ; DO WE HAVE TO ACTIVATE NOW? 481: JRST ACTIV1 ; YES, DO SO 482: HLLM I,LETAB-DPYL0(DAT) ;UPDATE THE STATUS BITS. 483: POPJ P, 484: 485: CKNFOR: TLOE I,EOLBT ;AT END OF LINE ALREADY ? 486: JRST LECX ;YES. CAN'T MOVE FORWARD. 487: ADD AC1,CCPOS(I) ;FIND POS. AFTER MOVE. 488: CAMGE AC1,FCPOS(I) ;WILL MOVE TAKE US TO END OF LINE ? 489: TLZA I,EOLBT ;NO. RESET FLAG SAYING WE ARE THERE. 490: MOVE AC1,FCPOS(I) ;YES. DON'T LET IT TAKE US PAST END. 491: EXCH AC1,CCPOS(I) ;PUT BACK NEW POSITION. 492: SUB AC1,CCPOS(I) ;GET -NO. OF PLACES TO MOVE. 493: JRST (TAC) ;RETURN. 495: LEBS: CAIN UCHN,CBIT2!CBIT1 496: JRST LE2 ;LET USER SEE CTRL-META BS 497: SKIPN CCPOS(I) ;BACKSPACE OR CTRL BACKSPACE. 498: JRST LECX ;AT START OF LINE. 499: TRZE UCHN,CBIT2 500: JRST .+3 ;META-BS ALWAYS DELETES 501: TLNN I,EOLBT!INSBT ;ARE WE AT END OF LINE OR IN INSERT MODE ? 502: HRRI UCHN,10 ;NO. FORCE NON-DELETING BS. 503: MOVN AC1,NUMARG(I) ;- RPT. ARG. 504: ADDM AC1,CCPOS(I) ;POSITION AFTER MOVE. 505: SKIPL AC2,CCPOS(I) ;WILL MOVE GO PAST START OF LINE 506: JRST BSP1 ;NO. 507: SUB AC1,AC2 ;YES. RE-ADJUST CNT. SO IT WON'T. 508: SETZM CCPOS(I) ;MARK AT BEGINNING OF LINE. 509: BSP1: JUMPG UCHN,BSP3 ;CTRL BITS ? 510: BSP2: ADDM AC1,FCPOS(I) ;NO. WE WILL ACTUALLY DELETE CHRS. 511: TLZ I,NOCRBT ;THIS IS FOR BENEFIT OF INIT4. 512: TDZA CHR,CHR ;SET CHR TO 0 SO MOVEIT WILL DELETE. 513: BSP3: TLZ I,EOLBT ;CTRL BACKSPACE. NO LONGER ARE WE AT END OF LINE. 514: PUSHJ P,MOVEIT 515: MVBAK ;MOVE BACKWARD RIGHT AMOUNT. 516: MOVNS DSER,AC2 ;- NO. OF COLUMNS MOVED. 517: TLO I,NOTEXT ; MARK CURSOR CHANGE ONLY 518: JUMPG UCHN,MVX1 ;IF NON-DELETING BACKSPACE, JUST UPDATE CURSOR AND LEAVE. 519: TLZ I,NOTEXT ; AHA, TEXT IS CHANGED TOO! 520: MOVEM TAC1,LEPNT1(I) 521: PUSHJ P,ADJTB 522: SKIPA AC2,DSER 523: MOVE AC2,DSER 524: JRST MVX2 526: LECI: TLOE I,INSBT ;FLAG INSERT MODE. 527: JRST LECX ;ALREADY IN THAT MODE ! 528: TLO I,NOTFR ; THIS IS A SILENT ONE 529: PUSHJ P,LECX ;UPDATE STATUS WORD. 530: MOVN AC1,XDEL 531: INSP1: ASH AC1,-1 ;FOR INSERT MODE, WE MOVE CURSOR BY 532: ADDM AC1,LEPPV(I) ; 1/2 A CHAR. WIDTH. 533: LDB AC2,[POINT 11,LEPPV(I),21] 534: ;NOW THE Y POS. 535: ASH AC1,-=26 ;(MOVE IT BY 1/4 CHAR. WIDTH.) 536: SUB AC2,AC1 ;(MOVE IT IN OTHER DIRECTION,TOO.) 537: DPB AC2,[POINT 11,LEPPV(I),21] 538: POPJ P, 539: 540: LECD: JSP TAC,CKNFOR ;CTRL D. PREPARE TO MOVE FORWARD. 541: ADDM AC1,FCPOS(I) ;DECREMENT NO. OF CHRS. IN LINE. 542: ADDM AC1,CCPOS(I) ;DON'T INCREMENT THE CURRENT POSITION. 543: MOVEI CHR,0 ;SET TO DELETE... 544: PUSHJ P,MOVEIT ;MOVE FORWARD, DELETING. 545: MVFOR 546: JRST ADJNTB ; ADJUST NEXT TAB 548: ; THIS ROUTINE ADJUSTS THE NEXT TAB, AS GIVEN BY THE BYTE POINTER IN TAC. 549: ; THE COUNT OF THE NUMBER OF COLUMNS THE LINE HAS BEEN MOVED BY IS IN AC3. 550: 551: ADJNTB: PUSHJ P,ADJTB ; ADJUST OUR TABS 552: JRST LECX 553: JRST LECX 554: 555: ADJTB: TLNN I,TABB+NOTABB ;DO WE KNOW ABOUT NEXT TAB ? 556: PUSHJ P,FNTAB ;NO. FIND OUT. 557: TLNN I,TABB ;IS THERE ONE ? 558: POPJ P, ;NO. 559: ANDI AC3,7 ;COUNT MOD 8 OF CHRS. DELETED. 560: JUMPE AC3,CPOPJ ;NO CHANGE IF MULTIPLE OF 8. 561: MOVE AC2,NTABCT(I) ;GET SIZE OF NEXT TAB. 562: ADD AC2,AC3 ;NEW SIZE OF NEXT TAB. 563: MOVE TAC,NTABPT(I) ;PTR. TO LAST SPACE IN NEXT TAB. 564: CAIG AC2,10 ;IS NEW SIZE TOO BIG ? 565: JRST LECD5 ;NO. TAB NEEDS TO GROW. 566: SUBI AC2,10 567: EXCH AC2,NTABCT(I) ;YES. TAB MUST SHRINK. 568: SUB AC2,NTABCT(I) ;FIND OUT HOW MUCH TO SHRINK IT. 569: MOVEI AC1,0 570: LECD4A: DPB AC1,TAC ;NULL ONE OF THE SPACES IN THIS TAB. 571: ADD TAC,[XWD 70000,0] ;DECREMENT POINTER. 572: JUMPG TAC,.+2 573: SUB TAC,[XWD 430000,1] 574: SOJG AC2,LECD4A 575: LECD6: MOVEM TAC,NTABPT(I) ;STORE UPDATED PTR. 576: JRST CPOPJ1 577: 578: LECD5: MOVEI AC1," " ;PREPARE TO MAKE TAB GROW. 579: MOVEM AC2,NTABCT(I) ;STORE NEW SIZE. 580: LECD5A: ILDB TAC1,TAC 581: JUMPE TAC1,.+2 ;IS THERE A NULL NEXT ? 582: PUSHJ P,LEINSW ;NO. PUT SOME IN. 583: DPB AC1,TAC ;ADD A SPACE. 584: SOJG AC3,LECD5A 585: JRST LECD6 587: SEARCH: MOVEI AC1,1 ;PREPARE TO SEARCH FOR INDICATED CHR. 588: MOVEM CHR,TAC ;SAVE CHR. TO BE SEARCHED FOR. 589: MOVE AC3,LEPNT1(I) ;MAKE COPY OF CURRENT POINTER. 590: MOVEI TAC1,AC3 ;PARAMETER FOR GETEM. 591: PUSHJ P,GETEM ;SKIP OVER CURRENT CHR. BEFORE STARTING SEARCH. 592: SRCHL: PUSHJ P,GETEM ;GET NEXT CHR. FROM LINE. 593: CAIN CHR,EOLCHR ;ARE WE AT END OF LINE ? 594: JRST LECX ;YES. DO NOTHING, CHR. NOT FOUND. 595: CAMN CHR,TAC ;HAVE WE FOUND IT ? 596: SOSLE NUMARG(I) ;YES. IS THE REPEAT COUNT EXHAUSTED ? 597: AOJA AC1,SRCHL ;NO. COUNT PLACES MOVED AND LOOK SOME MORE. 598: TLZN I,KILLBT ;YES. ARE WE KILLING OR JUST MOVEING UP TO IT ? 599: JRST LECSP ;MOVEING. 600: JRST LECD ;KILLING. 601: 602: GETEM: ILDB CHR,(TAC1) ;GET A NON-NULL CHAR. FROM LINE. 603: JUMPE CHR,.-1 604: CAIN CHR,11 ;IS IT A TAB ? 605: TLCN I,XTABBT ;YUP. ALREADY INSIDE A TAB ? 606: TLNN I,XTABBT ;INSIDE A TAB ? 607: JRST GETEM1 ; NO, EXIT 608: CAIE CHR,11 ; ARE WE INSIDE A CRLF? 609: CAIN CHR," " 610: JRST GETEM2 ; NO. PASS OVER THE TAB. 611: TLO I,CRBIT ; YES, MARK THIS AS A LONG LINE CRLF 612: JRST GETEM ; LOOP BACK FOR NEXT CHARACTER 613: 614: GETEM1: TLZE I,CRBIT ; ARE WE COMING OUT OF A CRLF? 615: JRST GETEM ; YES, GET NEXT CHARACTER PAST IT 616: POPJ P, ; NO 617: 618: GETEM2: TLZ I,CRBIT 619: JRST GETEM 621: LEDESC: CAIN CHR,10044 622: JRST CLEAR 623: CAIN CHR,10041 624: JRST ESCHX 625: TLO I,NOTFR ; THIS IS A SILENT TRANSFER 626: TRZ DSER,40 ; CHANGE LOWER TO UPPER CASE 627: CAIN DSER,"F" ;AN F ? 628: JRST ESCF ;YES. GO SEE ABOUT FCS MODE. 629: CAIN DSER,"O" 630: JRST ESCO 631: CAIN DSER,"I" 632: JRST ESCI 633: CAIN DSER,"W" 634: JRST ESCW 635: CAIN DSER,"Q" 636: JRST ESCQ ;GET WHO LINE FOR NEXT JOB WITH SAME PROG NAME 637: CAIN DSER,"X" 638: JRST ESCX ;SET OR CLEAR UPDATE BIT IN XTIME FOR THIS JOB 639: CAIN DSER,"G" 640: JRST ESCG 641: CAIN DSER,"L" 642: JRST ESCL 643: CAIN DSER,"Y" 644: JRST ESCY 645: CAIN DSER,"N" 646: JRST ESCN 647: CAIN DSER,"E" 648: JRST ESCE 649: CAIN DSER,"J" 650: JRST ESCJ 651: CAIN DSER,"C" ; CLEAR SCREEN? 652: JRST ESCC ; YES, GO QUEUE UP AN ERASE REQUEST 653: CAIN DSER,"P" ; REFRESH HIS PAGE PRINTER? 654: JRST ESCP ; YES, GO QUEUE UP A PAGE PRINTER REQUEST 655: SKIPE III(I) ; THE REST OF THESE COMMANDS ONLY APPLY TO DATA DISK 656: JRST LECX1 ; IF III, JUST IGNORE 657: CAIN DSER,"H" 658: JRST ESCH ;HIDE (OR UNHIDE) HIS CHANNEL 659: CAIE DSER,"R" ; REFRESH HIS LINE EDITOR? 660: JRST LECX1 ; NO, LEAVE 661: ESCR: TLZ I,NOTEXT!NOTFR ; QUEUE UP A COMBINED TEXT AND CURSOR TRANSFER 662: JRST LECX1 663: 664: ESCP: JUMPL AC1,BRKP ;<BREAK>P DOES THE WORKS 665: HRLI AC2,LERFP ; USE THE MAGIC CLOCK LEVEL ROUTINE FOR REFRESHING THE PAGE 666: JRST ESCC1 668: ; WE GET HERE IF THE LOSER TYPES <ESC>C OR <ESC>¬C WHICH CAUSES 669: ; HIS SCREEN (IF HE IS A DATA DISC TYPE) TO GET ERASED TO BLACK OR 670: ; WHITE RESPECTIVLY. 671: 672: ESCC: SKIPE III(I) 673: JRST ESCC0 674: HRRZ AC2,CURPP(I) ; PICK UP PAGE PRINTER CONTROL BLOCK ADDRESS 675: MOVSI AC3,(1B5) ; PICK UP BLACK BIT 676: JUMPL AC1,.+3 677: ORM AC3,DDCW(AC2) 678: JRST .+2 679: ANDCAM AC3,DDCW(AC2) 680: ESCC0: MOVSI AC2,LEERS ; USE CLOCK LEVEL ROUTINE IN DPYSER THAT QUEUES IT UP 681: ESCC1: HRRI AC2,(I) ; PUT IN THE DPY PROGRAM HEADER ADDRESS 682: ESCC2: CONO PI,PIOFF 683: IDPB AC2,CLKQ 684: CONO PI,PION 685: JRST LECX1 686: 687: ; <BREAK>P CLEARS THE SCREEN AND REFRESHES BOTH THE PAGE 688: ; PRINTER AND THE LINE EDITOR. 689: 690: BRKP: HRLI AC2,RFPCS 691: JRST ESCC1 692: 693: CLEAR: CAIN UCHN,CBIT1 ; <CTRL>CLEAR? 694: JRST ESCU ; YES, UNHOLD 695: JUMPN UCHN,CPOPJ ; NO, JUST FLUSH LINE UNLESS IT'S GOT <META> 696: ; (FALL THROUGH INTO LECLR) 697: 698: ; THIS ROUTINE CLEARS THE LINE EDITOR BUFFER WITHOUT DISTURBING 699: ; ITS STATUS. THIS MEANS THAT THE INFORMATION AS TO WHETHER 700: ; THIS IS A RE-EDITED LINE IS PRESERVED. 701: 702: LECLR: SKIPN FCPOS(I) 703: POPJ P, 704: TLZ I,TABB!NOTABB!EOLBT 705: PUSHJ P,INIT3 706: MOVE AC1,FCPOS(I) ; JUST DELETE THAT MANY CHARACTERS 707: JRST LECD 709: ; ROUTINE TO PUT PAGE PRINTER IN HOLD 710: 711: ESCHX: SETOM DPHOLD(I) 712: JRST LECX1 713: 714: ; ROUTINE TO SET NUMBER OF GLITCHES BEFORE HOLD 715: 716: ESCJ: DPB AC1,[POINT 9,GWORD(I),26] 717: MOVEM AC1,GLHCNT(I) 718: TRNN AC1,-1 719: SETOM GLHCNT(I) 720: JRST LECX1 721: 722: ; SET NUMBER OF LINES BEFORE HOLD 723: 724: ESCE: DPB AC1,[POINT 9,GWORD(I),17] 725: MOVEM AC1,LHCNT(I) 726: TRNN AC1,-1 727: SETOM LHCNT(I) 728: JRST LECX1 729: 730: ; ROUTINE TO UNHOLD THE PAGE PRINTER 731: 732: ESCU: SETZ AC1, 733: EXCH AC1,DPHOLD(I) 734: JUMPE AC1,LECX1 735: HRRZ AC2,PRGNUM(I) 736: ADD AC2,[XWD UNHOLD,DPYL0] 737: JRST ESCC2 738: 739: ;SET OR CLEAR CONSOLE PRIVACY BIT 740: 741: ESCH: MOVSI AC3,400000 742: HLR AC1,PRGNUM(I) 743: JUMPL AC1,UNHIDE ;BREAK-H MEANS UNHIDE 744: TDNE AC3,DDTAB(AC1) 745: JRST LECX1 746: IORM AC3,DDTAB(AC1) 747: PUSHJ P,DDFLSH 748: JRST LECX1 749: 750: UNHIDE: ANDCAM AC3,DDTAB(AC1) 751: JRST LECX1 753: ; ROUTINE TO SET PAGE PRINTER GLITCHES/PAGE 754: 755: ESCG: HRLI AC2,PPGSET 756: JRST ESCY1 757: 758: ; LINES/GLITCH 759: 760: ESCL: HRLI AC2,PPLSET 761: JRST ESCY1 762: 763: ; Y-POSITION 764: 765: ESCY: HRLI AC2,PPYSET 766: ESCY1: HRRZM AC1,LEARG(I) 767: JRST ESCC1 768: 769: ; NORMALIZE PAGE PRINTER 770: 771: ESCN: MOVE DSER,AC1 772: HRREI TAC,-DDL0(LINE) 773: JUMPL TAC,.+2 774: PUSHJ P,VDESCN ;NORMALIZE VDS ON DD 775: MOVSI AC2,LEERSN 776: JUMPL DSER,ESCC1 777: MOVSI AC2,PPNSET 778: JRST ESCC1 780: ;ESCAPE W,Q. 781: 782: ESCW: JUMPGE AC1,ESCW1 ;TURN ON WHO LINE? 783: SETZM WHOTAB(I) ;TURN OFF WHO LINE 784: JRST LECX1 785: 786: ESCW2: TLZ AC1,-1 ;THIS IS WHERE [ESC] # Q DOES [ESC] # W 787: ESCW1: TRNN AC1,-1 788: LDB AC1,PJOBN ;GET JOB NUMBER OUT OF DDB IF NO ARGUMENT. 789: CAIL AC1,JOBN ;LEGAL JOB? 790: JRST LECX1 ;NO 791: ;PUT INTO WHO TIME TABLE 792: MOVE AC2,JBTSTS(AC1) ;GET JOB STATUS WORD. 793: TLNE AC2,JNA ;IS IT LOGGED IN? 794: HRROM AC1,WHOTAB(I) ;YES, STORE JOB #. ALSO PUT -1 IN INCR TIME SLOT. 795: SETZM WHORUN(I) ;CLEAR TIME TO UPDATE RUNTIME NEXT 796: JRST LECX1 ;THAT'S ALL. 797: 798: ESCQ: TRNE AC1,-1 ;ANY ARGUMENT? 799: JRST ESCW2 ;[ESC] # Q AND [BRK] # Q ARE SAME AS [ESC] # W 800: SKIPN TAC,WHOTAB(I) ;GET NUMBER OF JOB ON WHO LINE 801: LDB TAC,PJOBN ;NO WHO LINE. USE USER'S JOB. 802: ANDI TAC,-1 ;MAKE SURE TAC HAS ONLY THE JOB NUMBER 803: JUMPE TAC,LECX1 ;IF NOT LOGGED IN AND NO WHO LINE UP, FORGET IT 804: HRRZ AC2,PRJPRG(TAC) ;GET PROGRAMMER NAME OF OLD WHO LINE JOB 805: MOVEI AC3,1 ;ASSUME POSITIVE INCREMENT FOR GOING THRU TABLE 806: JUMPGE AC1,.+2 ; UNLESS HE SAID [BRK] Q 807: SETO AC3, ; IN WHICH CASE WE USE NEGATIVE INCREMENT 808: PUSHJ P,ESCQ1 ;LOOK FROM TAC TO END OF TABLE 809: XORI TAC,JOBN ;START OVER AT OTHER END OF TABLE 810: PUSHJ P,ESCQ1 ; AND LOOK THROUGH WHOLE TABLE 811: JRST LECX1 ;NO JOB FOUND WITH SAME PN, NOT EVEN ORIGINAL JOB. 812: 813: ESCQ1: ADD TAC,AC3 ;MOVE ON TO NEXT JOB 814: CAIGE TAC,JOBN ;AT END OF TABLE YET? 815: JUMPG TAC,.+2 ; OR AT BEGINNING OF TABLE? 816: POPJ P, ;YES TO ONE OF THESE 817: HRRZ AC1,PRJPRG(TAC) ;GET PROGRAMMER NAME FOR THIS JOB 818: CAIE AC1,(AC2) ;IS IT THE ONE WE ARE LOOKING FOR? 819: JRST ESCQ1 ;NO 820: HRROM TAC,WHOTAB(I) ;YES! SAVE JOB NUMBER. -1 INTO INCR TIME. 821: SETZM WHORUN(I) ; AND CLEAR TIME TO UPDATE RUNTIME NEXT 822: SUB P,[1,,1] ;DONT POPJ. ADJUST STACK 823: JRST LECX1 825: ;ESCAPE O,F,I,X. 826: 827: ESCO: MOVEI IOS,IOSUPR ;ASSUME AN UN-↑O. 828: ANDCAB IOS,DEVIOS(DDB) 829: JUMPL AC1,LECX1 830: PUSHJ P,LECX1 ;GET STATUS BITS STORED AND RESET. 831: PUSH P,I ; SAVE THE DPY PROGRAM HEADER 832: PUSHJ P,CONTOB ; DO A ↑O. 833: PUSHJ P,UTYPET ;AND MAKE SURE IT GETS OUT 834: POP P,I 835: POPJ P, 836: 837: ESCF: JUMPL AC1,.+2 838: TLOA DAT,FCS ;TURN ON THE ↑F BIT (FULL CHR. SET). 839: TLZ DAT,FCS ;WRONG. TURN IT OFF. 840: HLLM DAT,LINTAB(DAT) 841: JRST LECX1 842: 843: ; <ESC>I INTERRUPTS ON THE INTTTI BIT IN THE LEFT HALF 844: 845: ESCI: MOVSI AC1,INTTTI 846: LDB AC2,PJOBN 847: TDNN AC1,JBTIEN(AC2) 848: JRST LECX1 849: ORM AC1,JBTIRQ(AC2) 850: SETOM INTREQ(PID) 851: JRST LECX1 852: 853: ESCX: LDB AC2,PJOBN ;GET JOB NUMBER OF THIS GUY 854: JUMPE AC2,LECX1 ;IF YOU'RE NOT LOGGED IN, I CANT HELP YOU 855: MOVSI TAC,400000 ;THIS IS THE BIT WE WILL SET OR CLEAR 856: JUMPN AC1,.+3 ;WAS IT PLAIN [ESC]X? 857: ANDCAM TAC,XTIME(AC2) ;YES. TURN OFF THE NO-UPDATE BIT IN XTIME 858: JRST LECX1 ;BYE 859: TRNE AC1,-1 ;WAS THERE AN ARGUMENT TO ESCAPE COMMAND? 860: JRST .+3 ;YES 861: ORM TAC,XTIME(AC2) ;NO. MUST HAVE BEEN [BRK]X. TURN ON NO-UPDATE FLAG 862: JRST LECX1 863: SETZ AC3, 864: HRRZS DSKOPS(AC2) ;MAKE ALL DISK OPS "RECENT" 865: JUMPL AC1,ESCX1 ;WAS IT [ESC] OR [BRK]? 866: SKIPGE AC3,JBTWAT(AC2) ;[ESC]1 X. UPDATE JB2WAT 867: ADD AC3,UPTIME ;MAKE WAIT TIME HONEST 868: HRLS DSKOPS(AC2) ;ZERO INCREMENTAL COUNT OF DISK OPERATIONS 869: ADD TAC,TTIME(AC2) ;[ESC]1 X. UPDATE XTIME AND SET NO-UPDATE BIT 870: ESCX1: MOVEM TAC,XTIME(AC2) ;[BRK]1 X MEANS CLEAR XTIME AND SET NO-UPDATE BIT 871: MOVEM AC3,JB2WAT(AC2) ;SAVE NEW VALUE OF OLD WAIT TIME 872: JRST LECX1 874: FNTAB: TLO I,NOTABB ;PREPARE TO FIND NEXT TAB IN LINE. 875: FNT1: ILDB TAC,TAC1 ;LOOK AT NEXT CHR. 876: CAIN TAC,EOLCHR ;ARE WE AT END OF LINE ? 877: POPJ P, ;YUP. RETURN LEAVING `NO TAB' BIT SET. 878: CAIE TAC,11 ;A TAB ? 879: JRST FNT1 ;NO. 880: MOVE AC2,TAC1 ; SEE IF THIS TAB IS REALLY A LONG LINE CRLF 881: ILDB AC2,AC2 ; PICK UP CHARACTER PAST TAB 882: CAIN AC2," " ; IS IT A SPACE? 883: JRST FNT3 ; YES, MUST BE REAL TAB 884: FNT4: ILDB TAC,TAC1 ; NO, MUST BE LONG LINE CRLF. READ PAST IT. 885: CAIE TAC,11 ; IS THIS A TAB? 886: JRST FNT4 ; NO, READ SOME MORE 887: JRST FNT1 ; YES, GET NEXT CHARACTER PAST CRLF 888: 889: FNT3: MOVEI AC2,0 ;COUNT NO. OF SPACES IN TAB. 890: TLC I,TABB!NOTABB ;SET BITS PROPERLY. 891: FNT2: ILDB TAC,TAC1 892: JUMPE TAC,.-1 ; SKIP NULLS 893: CAIE TAC," " ;ARE WE OUT OF SPACES YET ? 894: JRST FNT5 895: MOVEM TAC1,NTABPT(I) ;STORE PTR. TO LAST SPACE IN TAB. 896: AOJA AC2,FNT2 ;NO. KEEP COUNTING. 897: 898: FNT5: CAIE TAC,11 ; IS THIS REALLY THE TERMINATING TAB? 899: JRST FNT2 ; NO, GO BACK FOR MORE 900: MOVEM AC2,NTABCT(I) ;STORE SIZE OF TAB. 901: POPJ P, 903: ;;MOVEIT MOVES THE PTR. FORWARD OR BACKWARD BY THE NO. OF PLACES 904: ;; IN AC1, AND DELETES CHARS. PASSED OVER IF CHR=0. 905: 906: MOVEIT: MOVE TAC1,LEPNT1(I) ;GET CURRENT POINTER. 907: SETZB AC2,AC3 908: POP P,DSER ;GET PTR. TO ARGUMENT. 909: MOVEM AC1,1(P) ;REMEMBER COUNT. 910: SKIPN CHR ; ARE WE DELETING? 911: TLO I,NOBRBT ; YES, REDO THE LONG-LINE CRLF WHEN DONE 912: TLZ I,XTABBT ; CLEAR TAB BIT 913: JRST @(DSER) ;GO TO EITHER MVFOR OR MVBAK. 914: 915: MVFOR: ILDB TAC,TAC1 ;LOOK AT NEXT CHR. 916: JUMPE TAC,.-1 ;IGNORE NULLS. 917: JUMPN CHR,MVA ;DON'T DELETE UNLESS CHR =0. 918: DPB CHR,TAC1 ;DELETE IT. 919: JRST MVA 920: 921: MVBAK: LDB TAC,TAC1 ;LOOK AT CURENT CHR. 922: JUMPN CHR,.+2 ;DELETE IT IF APPROPRIATE, 923: DPB CHR,TAC1 924: ADD TAC1,[XWD 070000,0] ;DECREMENT POINTER. 925: JUMPG TAC1,.+2 926: SUB TAC1,[XWD 430000,1] 927: JUMPE TAC,MVBAK ;IF CURRENT CHR. WAS NULL,GET ANOTHER. 928: MVA: CAIN TAC,11 ;HAVE WE JUST ENCOUNTERED A TAB ? 929: ADDI AC3,1 ;YES. 930: TRNN AC3,1 ;ARE WE INSIDE A TAB ? 931: JRST MVA1 ; NO 932: CAIN TAC,11 ; YES, IS THIS A REAL TAB OR A LONG LINE CRLF? 933: AOJA AC2,@(DSER) 934: CAIN TAC," " 935: JRST MVA2 ; MUST BE A REAL TAB, SET THE BIT THAT SAYS SO 936: SKIPE CHR ; IF WE ARE DELETING, WE MUST REPOSITION THE CRLF 937: TLO I,NOBRBT ; DO SO BY PRETENDING THERE HAVEN'T BEEN ANY 938: CAIE TAC,15 ; BUMP COUNT ONE AT THE CR TO MAKE THE ENTIRE CRLF INVISIBLE 939: JRST @(DSER) ; OTHERWISE, JUST LOOP AROUND 940: TLNE I,XTABBT ; IF THIS IS A LONG LINE CRLF ONLY, THEN 941: JRST @(DSER) 942: SUBI AC1,1 ; CORRECT COUNT 943: AOJA AC2,@(DSER) 944: 945: MVA1: TLZ I,XTABBT 946: AOJL AC1,@(DSER) ; COUNT DOWN RPT. CNT AND LOOP. 947: JUMPE AC3,.+2 ;ALL DONE. DID WE PASS ANY TABS ? 948: TLZ I,TABB!NOTABB ;YES. WE NO LONGER KNOW WHERE NEXT ONE IS. 949: SUB AC2,1(P) ;ADD NO. OF CHRS. PASSED TO NO. OF SPACES IN TABS PASSED. 950: SUBB AC2,AC3 ;SUB. 2⊗NO. OF TABS. THIS (MIRABILE DICTU!) GIVES NO. OF COLUMNS MOVED. 951: JRST 1(DSER) 952: 953: MVA2: TLO I,XTABBT 954: AOJA AC2,@(DSER) 956: INIT2: MOVE TAC,ACTMOD(DDB) ;GET SPECIAL BITS 957: TRNN TAC,SUPCCR ;SUPPRESS CTRL CR? 958: CAIE CHR,1B28!15 ;HAS LOSER TYPED CTRL1 CR ? 959: JRST INITIT ;NO. RESET EVERYTHING FOR NEW LINE. 960: SKIPN LEPNT1(I) ; HAVE WE INITIALIZED AT LEAST ONCE? 961: JRST INITIT ; NO, DO SO NOW. 962: PUSHJ P,QLETXT ; QUEUE UP A TRANSFER IF DD 963: INIT4: HRLI I,400000!REEDBT!NOCRBT 964: SETZM LCH(I) 965: JUMPGE UCHN,INIT4B 966: TLNE DAT,LERSEE 967: TLO I,SHLDRB 968: ;LET LOSER EDIT PREVIOUS LINE SOME MORE. 969: INIT4B: MOVEI UUO,2 ;PREPARE TO REMOVE THE CR LF FROM END OF LINE. 970: INIT4A: LDB TAC,LEPNT1(I) ;(WE DON'T WANT TO LET THE LOSER EDIT THEM. ) 971: MOVNI AC1,1 ;TELL BACKSPACE ROUTINE TO DELETE ONE CHR. 972: CAIE TAC,12 ;IF IT IS A LF ... 973: CAIN TAC,15 ;... OR A CR ... 974: PUSHJ P,CRKILL ;... THEN WE THROW IT OUT. 975: SOJG UUO,INIT4A ;ALLOW FOR BOTH A LF AND A CR. 976: DPB UUO,PLASTC 977: TLZ I,NOTABB ;BS ROUTINE WILL HAVE SET THIS LOSER... 978: SKIPN FCPOS(I) ;IS LINE EMPTY? 979: TLO I,EOLBT ;YES, TELL SOMEONE PLEASE!!!!! 980: SOJA P,INIT3 ;RESET ONLY THE POINTER POSITION, AND RETURN UPLEVEL. 981: 982: ; THIS IS A ROUTINE FOR DELETING THE CRLF FROM THE END OF A LINE THAT 983: ; WE GOT FROM PTLOAD OR <CTRL-1>CR. 984: 985: CRKILL: ADDM AC1,FCPOS(I) ; DECREMENT THE TOTAL NUMBER OF CHARACTERS IN THE BUFFER 986: TLZ I,NOCRBT 987: SETZ CHR, ; FLAG DELETING OPERATION TO MOVEIT 988: PUSHJ P,MOVEIT ; BACK THE POINTER UP, DELETING THE CRLF AS IT GOES 989: MVBAK 990: MOVEM TAC1,LEPNT1(I) ; STORE THE UPDATED POINTER 991: POPJ P, 993: ; THIS IS THE INITIALIZE ROUTINE. HERE WE INITIALIZE ALL THE LINE 994: ; EDITOR VARIABLES 995: 996: INITIT: MOVEI TAC,EOLCHR*2+1 ;GET DPY CHAR. WORD WITH LINE TERMINATING CHR. IN IT. 997: MOVEM TAC,LEBUF(I) ;PLACE IN FIRST WORD OF BUFFER. 998: MOVEI TAC,LEB(I) ; PUT RETURN JUMP IN SECOND WORD 999: HRLI TAC,DISJMP 1000: MOVSM TAC,LEBUF+1(I) 1001: SETZM FCPOS(I) ;NO. OF CHARS. IN LINE. 1002: HRLI I,EOLBT+400000 1003: SETZM LCH(I) 1004: MOVEI TAC,LEBUF(I) ;GET START OF LINE BUFFER. 1005: HRRZM TAC,LELWD(I) ;INIT. PTR. TO RETURN JMP. 1006: INIT3: SETZM LEHPOS(I) ;HORIZONTAL POSITION. 1007: SETZM NUMARG(I) ; CLEAR THE REPEAT ARGUEMENT 1008: HLLM I,LETAB-DPYL0(DAT) ; STORE THE FLAG BITS BACK INTO THE LINE EDITOR TABLE 1009: SETZM CCPOS(I) ;CHARS. FROM START OF LINE. 1010: MOVE TAC,[LVW (12,-4,I,R,2,2)] 1011: MOVEM TAC,LEPPV(I) ;INITIAL POS. OF CURSOR. 1012: HRRZS LELMARG(I) ;RESET LEFT MARGIN. 1013: INIT1: HRLI TAC,440700 ;MAKE INITIAL BYTE PTR. 1014: HRRI TAC,LEBUF(I) 1015: MOVEM TAC,LEPNT1(I) 1016: POPJ P, 1017: 1018: SHIFT: JUMPG DSER,SHIFTL ;OVER LEFT MARGIN ? 1019: SHIFTR: SKIPA AC2,.+1 ;SHIFT LINE RIGHT. 1020: SHIFTL: MOVNI AC2,30 ;SHIFT LINE LEFT. 1021: SKIPN III(I) ; ARE WE A DD DISPLAY? 1022: POPJ P, ; IF SO, DON'T SHIFT LINE OVER, CAUSE IT SCREWS UP DPHPOS 1023: HRRES DSER,AC2 1024: IMUL AC2,XDEL 1025: ADDM AC2,LELMARG(I) ;MOVE WHOLE LINE OVER. 1026: JRST SHIFT2 ;SEE THE HAPPY RECURSIVE EDITOR ! 1028: ↑LACTIV:TDZA UCHN,UCHN ;NO SPURIOUS CTRL BITS PLEASE. 1029: PTLLX: PUSHJ P,STLNAC ;SETUP LINE! 1030: TLNN LINE,DISLIN!DDDLIN ;IF A DPY, XFER EDITOR BUFFER TO INPUT BUFFER NOW. 1031: POPJ P, ; IF NOT A DPY, RETURN NOW 1032: MOVE DAT,LINE 1033: SKIPGE I,LETAB-DPYL0(DAT) 1034: SKIPG CCPOS(I) 1035: POPJ P, ;NOTHING IN EDITOR BUFFER. FERGIT IT. 1036: ACTIV1: JUMPGE I,CPOPJ ;POOLE AND HIS RECURSIVE CALLS ON ACTIV1 ! 1037: TLC I,400000!WTFLAG ;READY FLAG OFF, WAIT FLAG ON. 1038: SETZ AC1, 1039: EXCH AC1,DPHOLD(I) 1040: JUMPE AC1,ACTNH ; IF NOT HOLDING, DON'T UNHOLD! 1041: HRRZ AC1,PRGNUM(I) 1042: ADD AC1,[XWD UNHOLD,DPYL0] 1043: CONO PI,PIOFF 1044: IDPB AC1,CLKQ 1045: CONO PI,PION 1046: ACTNH: AOJG UCHN,.+2 ;IS PTYSER PRE-LOADING US WITH A LINE TO EDIT ? 1047: PUSHJ P,INIT4 ;YOU BETCHUM, R.R. DON'T ACTIVATE GUY. 1048: PUSHJ P,INIT1 ;RESET LEPNT1. 1049: MOVEM UCHN,NTABPT(I) ;SAVE CTRL BITS OF ACTIVATION CHR. 1050: MOVE TAC,FCPOS(I) ;MAKE COPY OF NO. OF CHRS. IN BUFFER. 1051: TLZN I,REEDBT ;IS THIS A RE-EDIT ? 1052: JRST ACTNH0 1053: DPB UCHN,[POINT 2,CHR,28] 1054: SUBI CHR,200 1055: DPB CHR,[POINT 9,GWORD(I),35] 1056: DPB TAC,PLASTC ;YES. REMEMBER LINE LENGTH. 1057: MOVEI CHR,400 1058: TLZE I,SHLDRB ;IS loser looking over our shoulder ? 1059: PUSHJ P,LSRSEE ;Yes. Flag end of edit chrs. 1060: ACTNH0: MOVEM TAC,NTABCT(I) 1061: HLLM I,LETAB-DPYL0(DAT) ; STORE NEW STATUS. 1062: HRLI DAT,ACTIV3 ;DO THE DIRTY WORK AT CLOCK LEVEL. 1063: ; JRST DPYTIM 1064: ;PATCH BY RPH TO TRANSFER AS MANY CHARS AS WILL FIT IN 1065: ;TTY BUFFER NOW!!!!!! NOT LATER AT CLOCK LEVEL 1066: PUSH P,DAT ;SAVE LINE NUMBER 1067: PUSHJ P,ACTIV3 ;CALL HIM ONCE 1068: POP P,DAT ;GET BACK LINE NUMBER 1069: MOVE I,LETAB-DPYL0(DAT) ;AND BITS 1070: POPJ P, ;AND RETURN TO WHO EVER 1071: 1072: ACTIV5: MOVEI UCHN,TTIBUF(DDB) ;GET POINTER FOR PUTCHI. 1073: HRRZ DDB,I ; PICK UP ADDRESS OF DPY PROGRAM HEADER 1074: SKIPN III(I) ; IS IT A DATA DISC DISPLAY? 1075: TLO DDB,400000 ; YES, FLAG THAT FACT TO DPYTYO 1076: ACTIVL: MOVEM UCHN,DAT ;GIVE PUTCHI A PTR. TO INPUT BUFFER. 1077: MOVEI TAC1,LEPNT1(I) ;TELL GETEM TO USE LEPNT1. 1078: PUSHJ P,GETEM ;GET NEXT CHR. FROM BUFFER. 1079: PUSHJ P,PUTCHI ;PLACE CHAR. IN TTY INPUT BUFFER. 1080: JRST ACTIV2 ;INPUT BUFFER FULL. WAIT A WHILE. 1081: SOSN CCPOS(I) ;IS THIS THE ACTIVATION CHAR. ? 1082: SOSG TAC,NTABPT(I) ;YES. DOES IT HAVE CTRL. BITS ? 1083: JRST ACTIV6 ;NO. 1084: DPB TAC,[POINT 2,CHR,28] 1085: ;YES. PUT CTRL. BITS IN INPUT BUFFER. 1086: DPB CHR,PUTR(DAT) 1087: MOVEI CHR,13 ;ECHO CTRL. BITS, IF ANY. 1088: TRNE TAC,CBIT1 1089: PUSHJ P,ECHOCB 1090: MOVEI CHR,14 1091: TRNE TAC,CBIT2 1092: PUSHJ P,ECHOCB 1093: ACTIV6: LDB CHR,LEPNT1(I) ;GET BACK DPY VERSION OF CHAR. CODE. 1094: PUSHJ P,ECHO ;ECHO IT ON PAGE PRINTER. 1095: SKIPE III(I) ;ARE WE A DD 1096: JRST ACTIVQ 1097: LDB CHR,LEPNT1(I) ;GET LAST CHR PUT OUT 1098: CAIN CHR,177 ;IS IT A BS 1099: PUSHJ P,ECHO ;YES, ECHO TWICE FOR DD 1100: ACTIVQ: SOSLE NTABCT(I) ;ALL CHRS. XFERED ? 1101: JRST ACTIVL 1103: ; WE GET HERE WHEN THE LINE EDITOR BUFFER IS EMPTY. 1104: ; WE CLEAN UP AND LEAVE. 1105: 1106: MOVEI DDB,LEB(I) ; YES, MAKE EDITOR BUFFER INVISIBLE BY PUTTING 1107: HRLI DDB,DISJMP ; A RETURN JUMP ON TOP OF THE POSITION VECTOR 1108: MOVSM DDB,LEPPV(I) 1109: HRLI I,0 ;RESET STATUS BITS. 1110: TLZ IOS,SYNC!DDTM ;DONT SCREW UP THE COUNT 1111: ACTIV4: MOVEI DDB,-TTIBUF(UCHN) ;RECOVER DDB. 1112: PUSHJ P,STLNAC ;SET UP LINE. 1113: HLLM I,LETAB-DPYL0(LINE) ;RESET STATUS. 1114: PUSH P,TISYNC(DDB) ;REMEMBER CURRENT ACTIVATION COUNT! 1115: PUSHJ P,SYNCHK ;UPDATE TISYNC 1116: POP P,TAC ;GET BACK ORIGINAL COUNT 1117: CAMGE TAC,TISYNC(DDB) ;DID SYNCHK ACTIVATE SOME MORE CHARS? 1118: JRST RECIN3 ;YES, WAKE COMMAND DECODER! 1119: JRST RECIN4 1121: ACTIV2: TLO IOS,SYNC!DDTM ;FORCE ACTIVATION 1122: PUSHJ P,ACTIV4 ;GO ACTIVATE JOB. 1123: MOVE TAC,TTYTAB(LINE) 1124: TLNN TAC,400000 ;DOES HE ALREADY HAVE A COMMAND WAITING? 1125: PUSHJ P,COMSET ;NO, SET HIM 1126: MOVE DAT,LINE 1127: POPJ P, 1128: 1129: ;WE WILL GO TO ACTIV3 NEXT TIC. 1130: ↑ACTIV3: ;SET UP EVERYTHING AND GO BACK INTO LOOP. 1131: HRRZ LINE,DAT 1132: CAIL LINE,DPYL0 1133: CAIL LINE,DDL0+DDNUM 1134: POPJ P, 1135: MOVE I,LETAB-DPYL0(LINE) 1136: TLNN I,WTFLAG 1137: POPJ P, ; IF NOT DOING ANY TRANSFER, LEAVE 1138: SKIPN DDB,TTYTAB(DAT) 1139: JRST ACTIV7 ;SOMEBODY HAS FLUSHED OUR DDB. QUIT NOW. 1140: ACTIV9: MOVE IOS,DEVIOS(DDB) 1141: MOVE I,LETAB-DPYL0(LINE) 1142: JRST 2,@[ XWD 020000,ACTIV5] 1143: ;SUPPRESS INCREMENTING OF NEXT ILDB. 1144: 1145: ; WE GET HERE IF THE DDB HAS BEEN EATEN FROM UNDERNEATH US 1146: ; WE TRY TO GET HIM A NEW DDB. 1147: 1148: ACTIV7: CONO PI,SCNOFF 1149: SKIPE DDB,TTYTAB(DAT) ; SEE IF IT IS REALLY GONE? 1150: JRST ACTIV8 ; NOT REALLY, GO TO IT 1151: PUSHJ P,DDBSRC ; GET HIM A DDB 1152: JRST ACTI10 ; NONE AVAILABLE, REPLANT CLOCK REQUEST AND WAIT 1153: CONO PI,SCNON 1154: JRST ACTIV9 1155: 1156: ACTIV8: CONO PI,SCNON 1157: JRST ACTIV9 1158: 1159: ACTI10: CONO PI,SCNON 1160: JRST DPYTIM 1162: ECHOCB: TRNN IOS,NOECHB ;IS USER SUPPRESSING ECHO OF CTRL. BITS ? 1163: TRNE IOS,NOECHO ;OR ALL CHARS? 1164: TLNE IOS,TPMON ;YES, MONITOR GETS THEM ANYWAY 1165: JRST DPYTYO ;ECHO BIT 1166: POPJ P, 1167: 1168: ECHO: TLNE IOS,TPMON ; ALWAYS ECHO IN MONITOR MODE 1169: JRST DPYTYO 1170: TRNE IOS,NOECHO ;IS USER SUPPRESSING ALL ECHOING ? 1171: POPJ P, 1172: MOVE AC1,LCH(I) 1173: MOVEM CHR,LCH(I) 1174: CAIN CHR,12 1175: CAIE AC1,15 1176: JRST DPYTYO 1177: HRRZ AC1,PRGNUM(I) ; PICK UP TTY NUMBER 1178: MOVE AC1,LINTAB+DPYL0(AC1) ; FILL IN LINE CHARACTERISTICS 1179: TLNN AC1,XON ; LET THE LOSER TURN OFF LF AFTER CR IF HE WANTS TO 1180: JRST DPYTYO 1181: POPJ P, 1182: 1183: ↑PTLLED: ;IF WE'RE A DPY, WE WILL PRELOAD THE LINE EDITOR. 1184: TLNE LINE,IMLIN 1185: JRST IMLOAD 1186: TLNN LINE,DISLIN!DDDLIN 1187: POPJ P, 1188: HRRZS I,LETAB-DPYL0(LINE) 1189: ;SET NTABCT AS SIGNAL TO KBDED (ACTIV1). 1190: XCTR XR,[MOVE UUO,(UUO)] ;GET GUY'S PTR. 1191: TLNN UUO,-1 ;IS IT ALREADY (PRESUMABLY) A BYTE PTR. ? 1192: HRLI UUO,440700 ;NO. MAKE IT ONE. 1193: PTLL2: XCTR XLB,[ILDB CHR,UUO] ;GET CHR. FROM LOSER. 1194: MOVSI UCHN,-1 ;FLAG TO KBDED SAYING IT'S US. 1195: JUMPE CHR,PTLLX ;IF NULL, QUIT AND RESET EDITOR. 1196: PUSHJ P,PTLL3 ;FEED IT TO KBDED. 1197: TRNN UCHN,1 ;DID KBDED SEE AN ACTIVATION CHR. ? 1198: JRST PTLL2 ;NO. 1199: POPJ P, ;RESET EDITOR AND GO AWAY. 1200: 1202: ; HERE IS WHERE WE QUEUE UP LINE EDITOR TRANSFERS 1203: 1204: ↑↑QLETXT: SETOM LETXC(I) ; NOTE THAT TEXT HAS CHANGED 1205: QLECUR: SKIPE III(I) ; IF III, THIS IS IRRELEVANT 1206: POPJ P, 1207: SETO AC2, ; TEST THE FLAG 1208: EXCH AC2,LECLK(I) ; IS THERE A CLOCK REQUEST ALREADY IN? 1209: JUMPL AC2,CPOPJ ; IF SO, HE WILL GET IT. 1210: HRR AC1,I ; IF NOT, MAKE UP ONE WITH THE DPY HEADER ADDRESS IN IT 1211: HRLI AC1,DPLED ; AND USE THE LINE EDITOR ROUTINE 1212: CONO PI,PIOFF 1213: IDPB AC1,CLKQ 1214: CONO PI,PION 1215: POPJ P, 1217: ; THIS IS A ROUTINE THAT GOES THROUGH THE LINE AND SETS UP EXTRA CRLFS TO BREAK 1218: ; LONG LINES. 1219: 1220: MAKECR: TLZ I,TABB!NOTABBT ; NEXT TAB IS UNKNOWN NOW 1221: TLNE I,400000 ; IS IT REALLY THERE? 1222: SKIPE III(I) 1223: POPJ P, ; NOT THERE OR III 1224: ↑↑LEFIX:SETZ AC3, 1225: MOVE AC2,CURPP(I) ; PICK UP PAGE PRINTER CONTROL BLOCK ADDRESS 1226: MOVE AC1,PPHPOS(I) 1227: SUB AC1,LNLNGT(AC2) ;ROOM LEFT TO END OF LINE 1228: HRLI TAC,440700 ; PICK UP BYTE POINTER TO BEGINNING OF BUFFER 1229: HRRI TAC,LEBUF(I) 1230: SETZM NCRS(I) ; INITIALIZE THE TRANSFER LENGTH COUNTER 1231: MAKEC1: ILDB CHR,TAC ; PICK UP CHARACTER 1232: JUMPE CHR,.-1 ; SKIP NULLS 1233: CAIN CHR,EOLCHR ; IF END OF BUFFER, 1234: JRST MAKEC6 ; LEAVE 1235: CAIN CHR,11 ; IS THIS A TAB? 1236: JRST MAKEC2 ; YES, IT IS, GO PROCESS IT 1237: AOJL AC1,MAKEC7 ; NORMAL CHARACTER, BUMP COLLUMN COUNT 1239: ; WE GET HERE IF THE LINE IS LONG AND MUST BE BROKEN UP. 1240: 1241: MAKE12: MOVE AC1,TAC ; PICK UP BYTE POINTER 1242: MAKE23: ILDB CHR,AC1 ; LOOK AHEAD SOME 1243: JUMPE CHR,.-1 1244: CAIE CHR,11 ; MAYBE THIS IS JUST THE LONG-LINE CRLF? 1245: JRST MAKE20 ; APPARANTLY NOT, BUMP CR COUNT 1246: ILDB CHR,AC1 ; PICK UP NEXT CHARACTER 1247: JUMPE CHR,.-1 1248: CAIE CHR,15 ; IF THIS IS A CR, IS DEFINITELY A LONG-LINE CRLF 1249: JRST MAKE21 1250: MAKE22: ILDB CHR,AC1 ; IN WHICH CASE, READ PAST IT 1251: CAIE CHR,11 1252: JRST MAKE22 1253: JRST MAKE23 1254: 1255: MAKE20: CAIE CHR,EOLCHR ; IF THERE ARE NO MORE CHARACTERS ON NEXT LINE, DON'T BUMP LINE COUNT 1256: MAKE21: AOS NCRS(I) ; END OF LINE, BREAK THE LINE UP 1257: MOVEI CHR,11 ; END OF LINE, BREAK LINE 1258: PUSHJ P,MAKINS 1259: MOVEI CHR,15 1260: PUSHJ P,MAKINS 1261: MOVEI CHR,12 1262: PUSHJ P,MAKINS 1263: MOVEI CHR,11 1264: PUSHJ P,MAKINS 1265: MOVN AC1,LNLNGT(AC2) ; RESET COLUMN COUNT 1266: MAKEC8: MOVE TAC1,TAC ; SAVE POINTER 1267: MAKEC9: ILDB CHR,TAC1 ; IS NEXT CHARACTER A NULL? 1268: JUMPN CHR,MAKEC7 ; NO, ALL OK 1269: MOVE TAC,TAC1 ; YES, SPACE POINTER OUT PAST NULLS 1270: JRST MAKEC9 1271: 1272: MAKEC7: ADDI AC3,1 ; BUMP COLUMN COUNT 1273: MAKE10: CAMN AC3,CCPOS(I) ; IS THIS WHERE THE POINTER IS SUPPOSED TO BE? 1274: MOVEM TAC,LEPNT1(I) ; YES, STORE IT 1275: JRST MAKEC1 1277: ; HERE WE SEE IF THE TAB IS A REAL TAB OR IF IT IS JUST 1278: ; THE THING WE USE TO DELIMIT A LONG-LINE CRLF 1279: 1280: MAKEC2: MOVE TAC1,TAC ; SAVE BYTE POINTER 1281: ILDB CHR,TAC ; PICK UP NEXT CHARACTER 1282: CAIE CHR,15 ; IS IT A CR? 1283: JRST MAKEC3 ; NO, MUST BE REGULAR TAB, GO ADJUST IT 1284: SETZ DSER, 1285: DPB DSER,TAC1 ; YES, ZERO OUT THE LONG LINE CRLF 1286: DPB DSER,TAC 1287: IDPB DSER,TAC 1288: IDPB DSER,TAC 1289: JRST MAKE10 1290: 1291: MAKEC6: SETZ CHR, ; ZERO OUT STUFF AFTER END OF LINE CHARACTER 1292: MAKE17: LDB TAC1,[POINT 6,TAC,5] 1293: CAIG TAC1,7 ; IS THERE ANY MORE ROOM IN THE LAST TEXT WORD 1294: JRST MAKE18 ; NO, SET UP LELWD AND LEAVE 1295: IDPB CHR,TAC ; YES, PLOP DOWN A ZERO THERE 1296: JRST MAKE17 1297: 1298: MAKE18: HRRZ TAC1,TAC ; GET BARE ADDRESS OF LAST TEXT WORD IN BUFFER 1299: EXCH TAC1,LELWD(I) ; STORE IT AND GET THE OLD VALUE 1300: MOVE AC1,1(TAC1) ; PICK UP THE RETURN JUMP 1301: MOVEM AC1,1(TAC) ; PUT IT RIGHT AFTER THE END OF LINE CHARACTER 1302: POPJ P, 1304: ; WE GET HERE WHEN THE TAB SURROUNDS A BUNCH OF SPACES. FIRST WE 1305: ; DELETE THE ORIGINAL SPACES, THEN WE FIGURE OUT HOW MANY WE NEED 1306: ; TO MAKE THE TAB COME OUT RIGHT AND PUT THEM IN. 1307: 1308: MAKEC3: PUSH P,AC3 ; SAVE BYTE POINTER 1309: PUSH P,UUO ; GET AN ACCUMULATOR FOR COUNTING SPACES IN TABS 1310: SETZB DSER,UUO 1311: MAKEC4: DPB DSER,TAC ; ZERO OUT THE SPACES IN THE TAB 1312: CAIN CHR," " ; COUNT IT AS A SPACE ONLY IF IT REALY IS A SPACE 1313: ADDI UUO,1 ; BUMP NUMBER OF SPACES IN THIS TAB 1314: ILDB CHR,TAC 1315: CAIE CHR,11 ; UNTIL WE GET TO THE TERMINATING TAB 1316: JRST MAKEC4 1317: MOVE TAC,NCRS(I) ; FIGURE OUT POSITION FROM BEGINNING OF FIRST LINE 1318: ADDI TAC,1 ; BUMP BY ONE TO CORRECT FOR NEGATIVITY OF AC1 1319: IMUL TAC,LNLNGT(AC2) ; MULTIPLY NUMBER OF LINES BY LENGTH OF LINES 1320: ADD TAC,AC1 ; ADD IN CHARACTERS INTO LAST LINE 1321: MOVEM TAC,LECHPS(I) ; SAVE FOR FUTURE REFERENCE 1322: ANDI TAC,7 ; MOD 10 1323: MOVEI AC3,10 1324: SUB AC3,TAC ; THIS IS NUMBER OF COLUMNS TO GO 1325: ADD AC1,AC3 ; ADD LENGTH OF TAB INTO COLUMN POSITION 1326: SUBM AC3,UUO ; GET CORRECTION TO THIS TAB 1327: JUMPLE AC1,MAKE13 ; IF NOT AT END OF LINE, GO ON AND ADJUST TAB 1328: MOVE TAC,TAC1 ; GET POINTER TO TAB 1329: MOVEI CHR," " ; NOW SPACE OUT TO END OF LINE 1330: MAKE16: CAML AC1,AC3 ; OUT FAR ENOUGH? 1331: JRST MAKE15 ; YES, PUT IN CRLF NOW 1332: PUSHJ P,MAKINS ; NO, PUT IN ANOTHER SPACE 1333: SOJA AC3,MAKE16 1335: ; AT THIS POINT, WE ARE IN THE PROCESS OF BREAKING A LONG LINE 1336: ; IN THE MIDDLE OF A TAB. WE HAVE JUST INSERTED THE APROPRIATE 1337: ; NUMBER OF SPACES TO FILL OUT THE LAST LINE, AND NOW WE 1338: ; MUST INSERT THE CRLF ITSELF. 1339: 1340: MAKE15: MOVEI CHR,15 1341: PUSHJ P,MAKINS ; BREAK LINE IN THE MIDDLE OF A TAB 1342: MOVEI CHR,12 1343: PUSHJ P,MAKINS 1344: AOS NCRS(I) ; UPDATE NUMBER OF CRLFS IN LINE 1345: MOVE TAC1,TAC ; SAVE BYTE POINTER TO TAB 1346: MOVE AC3,AC1 ; NUMBER OF SPACES IS NUMBER OF CHARACTERS INTO LINE 1347: SUB AC1,LNLNGT(AC2) ; RESET COLUMN COUNT 1348: MAKE13: MOVE TAC,LECHPS(I) ; PICK UP NUMBER OF CHARACTERS FROM FIRST LINE 1349: CAMGE TAC,LEHPOS(I) ; ARE WE BEFORE THE HORIZONTAL POSITION POINTER? 1350: ADDM UUO,LEHPOS(I) ; YES, UPDATE IT 1351: MAKE14: POP P,UUO 1352: MOVE TAC,TAC1 ; GET BYTE POINTER BACK 1353: MOVEI CHR,40 1354: PUSHJ P,MAKINS ; INSERT THAT MANY SPACES 1355: SOJG AC3,.-1 1356: LDB CHR,TAC ; NOW UPDATE POINTER TO PAST TAB 1357: MAKEC5: CAIN CHR,11 1358: JRST MAKE11 ; THEN GET BACK INTO THE LOOP 1359: ILDB CHR,TAC ; NOT TAB, GET NEXT CHARACTER 1360: JRST MAKEC5 1362: MAKE11: POP P,AC3 ; RESTORE COLUMN COUNT 1363: JUMPGE AC1,MAKE12 ; IF WE GOT LINE OVERFLOW, BREAK LINE UP 1364: JRST MAKEC8 1365: 1366: MAKINS: ILDB TAC1,TAC ; IS THIS CHARACTER A NULL? 1367: JUMPE TAC1,.+2 1368: PUSHJ P,LEINSW ; NO, INSERT A WORD OF NULLS 1369: DPB CHR,TAC ; DEPOSIT OUR CHARACTER OVER A NULL 1370: POPJ P, 1371: 1372: BEND LINED 1373: BEND TTYSER